package com.weixin.controller.callback;

import com.weixin.config.WeiXinProperties;
import com.weixin.config.aes.MessageUtil;
import com.weixin.config.aes.WXBizMsgCrypt;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Map;

/**
 * @author zjd
 * @Title:
 * @Description:
 * @date 2021/4/1414:27
 */
@Api("企业微信客户联系回调")
@Controller
public class QyCustomerCallbackController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * get 请求  验签.
     *
     * @param msgSignature 加密
     * @param timestamp    时间戳
     * @param nonce        随机
     * @param echostr      加密内容
     * @param response
     * @throws Exception
     */
    @ApiOperation("企业回调的url get方式 该url不做任何的业务逻辑，仅仅微信查看是否可以调通")
    @GetMapping("/customer/callback")
    public void reveiceMsg(@RequestParam(name = "msg_signature")  String msgSignature,
                           @RequestParam(name = "timestamp")  String timestamp,
                           @RequestParam(name = "nonce")  String nonce,
                           @RequestParam(name = "echostr")  String echostr,
                           final HttpServletResponse response) throws Exception {
        WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(WeiXinProperties.getToken(), WeiXinProperties.getEncodingAESKey(), WeiXinProperties.getCorpId());
        //企业回调的url-----该url不做任何的业务逻辑，仅仅微信查看是否可以调通.
        //String keyWord = URLDecoder.decode("%C4%E3%BA%C3", "UTF8");
        String sEchoStr; //需要返回的明文
        logger.info(" 企业微信客户联系回调检测 msg_signature {}, timestamp {}, nonce {} , echostr {}", msgSignature, timestamp, nonce, echostr);
        sEchoStr = wxcpt.VerifyURL(msgSignature, timestamp,
                nonce, echostr);
        PrintWriter out = response.getWriter();
        try {
            //必须要返回解密之后的明文
            if (StringUtils.isBlank(sEchoStr)) {
                logger.info("URL验证失败");
            } else {
                logger.info("验证成功!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        out.write(sEchoStr);
        out.flush();
    }

    /**
     * 企业微信通讯录回调.
     *
     * @param request       request
     * @param sMsgSignature 签名
     * @param sTimestamp    时间戳
     * @param sNonce        随机值
     * @return success
     */
    @ResponseBody
    @PostMapping(value = "/customer/callback")
    public ResponseEntity acceptMessage(final HttpServletRequest request,
                                        @RequestParam(name = "msg_signature")  String sMsgSignature,
                                        @RequestParam(name = "timestamp")  String sTimestamp,
                                        @RequestParam(name = "nonce")  String sNonce) {
        logger.info("企业微信客户联系回调 msg_signature {}, timestamp {}, nonce {} ", sMsgSignature, sTimestamp, sNonce);
        try {
            WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(WeiXinProperties.getToken(), WeiXinProperties.getEncodingAESKey(), WeiXinProperties.getCorpId());
            InputStream inputStream = request.getInputStream();
            String sPostData = IOUtils.toString(inputStream, "UTF-8");
            String sMsg = wxcpt.DecryptMsg(sMsgSignature, sTimestamp, sNonce, sPostData);
            System.out.println("after decrypt msg: " + sMsg);
            Map<String, String> dataMap = MessageUtil.parseXml(sMsg);
            //处理逻辑
            System.out.println(dataMap);
        }catch (Exception e){
            e.printStackTrace();
        }

        return new ResponseEntity(HttpStatus.OK);
    }
}
